package yunquan.wang.jbpm5.web;

import java.io.File;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseFactory;
import org.drools.SystemEventListenerFactory;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;
import org.drools.impl.EnvironmentFactory;
import org.drools.io.ResourceFactory;
import org.drools.persistence.jpa.JPAKnowledgeService;
import org.drools.runtime.Environment;
import org.drools.runtime.EnvironmentName;
import org.drools.runtime.KnowledgeSessionConfiguration;
import org.drools.runtime.StatefulKnowledgeSession;
import org.drools.runtime.process.WorkItemHandler;
import org.jbpm.process.audit.JPAWorkingMemoryDbLogger;
import org.jbpm.process.workitem.wsht.GenericHTWorkItemHandler;
import org.jbpm.task.TaskService;
import org.jbpm.task.service.local.LocalTaskService;

import yunquan.wang.test.reg.RegTest;

public class JbpmTools {
	private KnowledgeBase kbase;
	private static StatefulKnowledgeSession ksession;
private 	static org.jbpm.task.TaskService client;
	/**
	 * 流程（知识）存储库，属于重量级容器，一般就初始化一次
	 * @return
	 */
	private KnowledgeBase buildKnowlegeBase() {
		// 知识库装载器
		KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
		//循环扫描Classpath下指定目录的文件，流程图放入知识库中
		URL processpath=	RegTest.class.getClassLoader().getResource("process");
		   File processes=new File(processpath.getFile());
		 File [] all=  processes.listFiles();
		 for(File file:all)
		 {
				// 编译添加到库里，ResourceFactory 提供了多种添加库的方法，ResourceType 提供了多种资源类型，进行统一管理
				kbuilder.add(ResourceFactory.newFileResource(file),ResourceType.BPMN2);
		 }
		// 从库工厂返回知识库
		return kbuilder.newKnowledgeBase();
	}
/**
 * 根据知识库，创建流程会话。
 * @param kbase
 * @return
 */
	private StatefulKnowledgeSession initSession() {
		if(kbase==null)
		{
			kbase=buildKnowlegeBase();
		}
		/**
		 * 流程运行时会话
		 */
		StatefulKnowledgeSession ksession;
		/**
		 * 创建JPA工厂，根据META-INF下的JPA unit
		 */
		   Map<String, String> map = new HashMap<String, String>();
			  map.put("hibernate.dialect", "org.hibernate.dialect.MySQL5InnoDBDialect");
		EntityManagerFactory emf = Persistence.createEntityManagerFactory("org.jbpm.persistence.jpa",map);
		//设置会话全局属性  数据连接工厂
		 Environment env = EnvironmentFactory.newEnvironment(); env.set(EnvironmentName.ENTITY_MANAGER_FACTORY, emf);
	       // env.set(EnvironmentName.TRANSACTION_MANAGER, TransactionManagerServices.getTransactionManager());
		
			KnowledgeSessionConfiguration conf = KnowledgeBaseFactory.newKnowledgeSessionConfiguration();
			ksession = JPAKnowledgeService.newStatefulKnowledgeSession( kbase, null, env );
			 new JPAWorkingMemoryDbLogger(ksession);
			 WorkItemHandler workItemHandler=null;
			 
			 GenericHTWorkItemHandler localworkItemHandler=new GenericHTWorkItemHandler(ksession);
			 //标明是本地的任务处理方式
			 localworkItemHandler.setLocal(true);
			 //客户端和服务器端是一个,用的本地获取方式
			 TaskService taskService =getClientTaskService();
			 //设置客户端
			 localworkItemHandler.setClient(taskService);
			  workItemHandler=localworkItemHandler;
			 	ksession.getWorkItemManager().registerWorkItemHandler("Human Task", workItemHandler);
			  // JPAProcessInstanceDbLog ;
			return ksession;

	}

	public static StatefulKnowledgeSession getSession()
	{
		if(ksession==null)
		{
			ksession=new JbpmTools().initSession();
		}
		return ksession;
	}
	
	public static org.jbpm.task.TaskService  getClient()
	{
		if(client==null)
		{
			client=new JbpmTools().getClientTaskService();
		}
		return client;
	}
	/**
	 * 客户端调用来操作人工任务是通过@See TaskService，有两种 
	 * 一种，是客户端和服务器均在一个环境中，则为@See LocalTaskService
	 * 另外一种，是通过网络服务的方式：即@See SyncTaskServiceWrapper,因为调用服务器通信需要延迟，因此，用一个同步包装器来保证实时的返回
	 * 同步调用网络的构造方式为一个@See TaskClient ，TaskClient封装了基本操作，
	 * 所有的命令，通过一个@See TaskClientConnector 即底层的连接通讯方式来发送命令（Command）
	 * ,HornetQ 和Mina是两种实现方式
	 * @return
	 */
	private org.jbpm.task.TaskService getClientTaskService()
	{
		 TaskService service = new LocalTaskService(TaskServiceTools.getTaskStore());
		 return service;
	}
	
	

 

}
